/**
 * @file 用于存储actions 定义它触发原子操作 如果action较多可以建立文件夹
 */
import types from './types'
import api from '../util/http/api'
import { OPERATION_TYPE as OPTYPE } from '../type'

const traverseDir = (dispatch, memObj, url) => {
  let dirs = memObj.children
  if (!dirs) {
    dispatch('writeFileSync', {
      content: memObj.content || '',
      path: url + '/' + memObj.name
    })
    return
  }
  dispatch('mkdirSync', url + '/' + memObj.name)
  if (dirs && dirs.length) {
    for (let i = 0; i < dirs.length; i++) {
      traverseDir(dispatch, dirs[i], url + '/' + memObj.name)
    }
  }
}

export default {
  resetTerminalInfo ({ state }) {
    state.terminalInfo = {
      type: 'common',
      message: '欢迎使用hap-ide，编译之前请先保存...'
    }
  },
  changeTerminalInfo ({ state }, info) {
    state.terminalInfo = info
  },
  // 文件内容相关
  selectFile ({ commit }, file) {
    commit(types.HAP_FILE_SELECTED_FILE, file)
  },
  // 菜单相关
  changeMenuStatus ({ commit }, status) {
    commit(types.HAP_FILE_MENU_STATE, status)
  },
  changeMenuList ({ state }, list) {
    state.menuList = list
  },
  // 执行指令
  excuteDirec ({ dispatch }, item) {
    try {
      switch (item.dirtype) {
        case OPTYPE.CREATE_FILE.dirtype:
          dispatch(OPTYPE.CREATE_FILE.instruction, {path: item.fullName + '/' + item.name, content: ''})
          break
        case OPTYPE.CREATE_DIRECTORY.dirtype:
          dispatch(OPTYPE.CREATE_DIRECTORY.instruction, item.fullName + '/' + item.name)
          break
        case OPTYPE.DELETE_FILE.dirtype:
          dispatch(OPTYPE.DELETE_FILE.instruction, item.fullName)
          break
        case OPTYPE.DELETE_DIRECTORY.dirtype:
          dispatch(OPTYPE.DELETE_DIRECTORY.instruction, item.fullName)
          break
        case OPTYPE.RENAME_FILE.dirtype:
          dispatch(OPTYPE.RENAME_FILE.instruction, {path: item.fullName, name: item.name})
          break
        default:
          throw new Error(`${item.dirtype} 无法识别`)
      }
    } catch (e) {
      dispatch('toastsAdd', {
        type: 'DANGER',
        title: e
      })
    }
  },
  // MemoryFs操作相关
  mkdirpSync ({ state }, path) {
    state.memoryFs.mkdirpSync(path)
  },
  mkdirSync ({ state }, path) {
    state.memoryFs.mkdirSync(path)
  },
  rmdirSync ({ state, dispatch }, path) {
    state.memoryFs.rmdirSync(path)
    dispatch('selectFile', '')
  },
  unlinkSync ({ state, dispatch }, path) {
    state.memoryFs.unlinkSync(path)
    dispatch('selectFile', '')
  },
  writeFileSync ({ state }, { path, content }) {
    state.memoryFs.writeFileSync(path, content)
  },
  readdirSync ({ state, dispatch }, path) {
    try {
      return state.memoryFs.readdirSync(path)
    } catch (e) {
      dispatch('toastsAdd', {
        type: 'DANGER',
        title: e
      })
    }
  },
  readFileSync ({ state, dispatch }, path) {
    try {
      const result = state.memoryFs.readFileSync(path)
      state.fileObject = result
    } catch (e) {
      dispatch('toastsAdd', {
        type: 'DANGER',
        title: e
      })
    }
  },
  renameSync ({ state, dispatch }, { path, name }) {
    state.memoryFs.renameSync(path, name)
    dispatch('selectFile', '')
  },
  fileContentChange ({ state, dispatch }, { file, value }) {
    try {
      state.memoryFs.tempSaveFileSync(file, value)
    } catch (e) {
      dispatch('toastsAdd', {
        type: 'DANGER',
        title: e
      })
    }
  },
  fileSave ({ state, dispatch }, file) {
    try {
      state.memoryFs.saveFileSync(file)
    } catch (e) {
      dispatch('toastsAdd', {
        type: 'DANGER',
        title: e
      })
    }
  },
  // toast相关action
  toastsAdd ({ commit }, toast) {
    toast.timeoutId = setTimeout(() => commit(types.HAP_TOAST_FINISH), 3000)
    commit(types.HAP_TOAST_ADD, toast)
  },
  toastRemove ({ commit }, { index, timeoutId }) {
    if (timeoutId) {
      clearTimeout(timeoutId)
    }
    commit(types.HAP_TOAST_REMOVE, index)
  },
  // 请求api
  loadDirectory ({ state }, params = {}) {
    return api.get('loadDirectory', params)
  },
  saveDirectory ({ state }, params = {}) {
    return api.post('saveDirectory', params)
  },
  compileSourceToBundle ({ state }, params = {}) {
    return api.post('hapBuild', params)
  },
  // 处理请求返回的action
  initMemFs ({ dispatch }, files) {
    try {
      traverseDir(dispatch, files, '')
    } catch (e) {
      dispatch('toastsAdd', {
        type: 'DANGER',
        title: '初始化文件树失败'
      })
    }
    dispatch('toastsAdd', {
      type: 'SUCCESS',
      title: '初始化文件树成功'
    })
  },
  getFilesInfo ({ dispatch }, { params = {} } = {}) {
    return dispatch('loadDirectory', params).then(res => {
      dispatch('toastsAdd', {
        type: 'SUCCESS',
        title: '获取文件树成功',
        message: '开始初始化文件树'
      })
      dispatch('initMemFs', res.data && res.data.dir)
    }, rej => {
      dispatch('toastsAdd', {
        type: 'DANGER',
        title: '获取文件树失败'
      })
    })
  },
  saveFiles ({ dispatch }, {params = {}} = {}) {
    return dispatch('saveDirectory', params).then(res => {
      dispatch('changeTerminalInfo', {
        type: res.code === 200 ? 'success' : 'error',
        message: res.message
      })
    }, rej => {
      dispatch('toastsAdd', {
        type: 'DANGER',
        title: '保存失败'
      })
    })
  },
  compileSource ({ dispatch }, { params = {} } = {}) {
    return dispatch('compileSourceToBundle', params).then(res => {
      dispatch('changeTerminalInfo', {
        type: res.code === 200 ? 'success' : 'error',
        message: res.message && res.message.split('\n')
      })
    }, rej => {
      dispatch('toastsAdd', {
        type: 'DANGER',
        title: '编译失败'
      })
    })
  },
  changeBundleUrl ({ state }, url) {
    state.bundleSrc = url
  }
}
